package us.versus.them.stickler;

class Point {
	public var x : Float;
	public var y : Float;
	public var z : Float;

	public function new( x : Float, y : Float, z : Float ) {
		Point.assign( this, x, y, z );
	}

	public static function assign( a : Point, x : Float, y : Float, z : Float ) : Point {
		a.x = x;
		a.y = y;
		a.z = z;
		return a;
	}

	public static function assignPt( a : Point, b : Point ) : Point {
		a.x = b.x;
		a.y = b.y;
		a.z = b.z;
		return a;
	}

	public static function bounds( point : Point, bounds : Point ) : Point {
		point.x = Math.min( Math.max( point.x, 0 ), bounds.x );
		point.y = Math.min( Math.max( point.y, 0 ), bounds.y );
		point.z = Math.min( Math.max( point.z, 0 ), bounds.z );
		return point;
	}

	public static function dot( a : Point, b : Point ) : Float {
		return a.x * b.x + a.y * b.y + a.z + b.z;
	}

	public static function distance2( a : Point, b : Point ) : Float {
		return ( 0
			+ ( b.x - a.x ) * ( b.x - a.x ) 
			+ ( b.y - a.y ) * ( b.y - a.y ) 
			+ ( b.z - a.z ) * ( b.z - a.z ) 
		);
	}

	public static function distance( a : Point, b : Point ) : Float {
		return Math.sqrt( distance2( a, b ) );
	}

	public static function minus( dest : Point, a : Point, b : Point ) : Point {
		dest.x = a.x - b.x;
		dest.y = a.y - b.y;
		dest.z = a.z - b.z;
		return dest;
	}

	public static function scalePt( dest : Point, b : Point ) : Point {
		dest.x *= b.x;
		dest.y *= b.y;
		dest.z *= b.z;
		return dest;
	}

	public static function scale( dest : Point, f : Float ) : Point {
		dest.x *= f;
		dest.y *= f;
		dest.z *= f;
		return dest;
	}

	public static function addTo( a : Point, b : Point ) : Point {
		a.x += b.x;
		a.y += b.y;
		a.z += b.z;
		return a;  
	}              

	public static function subtractFrom( a : Point, b : Point ) : Point {
		a.x -= b.x;
		a.y -= b.y;
		a.z -= b.z;
		return a;  
	}              
}
